package org.jeecg.modules.system.service.impl;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.payscore.PostPayment;
import com.github.binarywang.wxpay.bean.payscore.TimeRange;
import com.github.binarywang.wxpay.bean.payscore.WxPayScoreRequest;
import com.github.binarywang.wxpay.bean.payscore.WxPayScoreResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.system.entity.OrderInfo;
import org.jeecg.modules.system.entity.SettingInfo;
import org.jeecg.modules.system.service.IDeviceInfoService;
import org.jeecg.modules.system.service.IOrderInfoService;
import org.jeecg.modules.system.service.ISettingInfoService;
import org.jeecg.modules.system.service.IWxPayScoreService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class WxPayScoreServiceImpl implements IWxPayScoreService {
    @Resource
    private WxPayService wxService;

    @Resource
    private IOrderInfoService orderInfoService;

    @Resource
    private IDeviceInfoService deviceInfoService;

    @Resource
    private ISettingInfoService settingInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result controlDevice(JSONObject data) {
        String deviceNo = data.getString("deviceNo");
        String outOrderNo = data.getString("outOrderNo");
        if(org.apache.commons.lang3.StringUtils.isAnyBlank(deviceNo,outOrderNo)){
            return Result.error("请求信息异常，请重新扫码操作");
        }
        try {
            WxPayScoreResult wxPayScoreResult = wxService.getPayScoreService().queryServiceOrder(outOrderNo, null);
            log.info("queryServiceOrder:{}", wxPayScoreResult);
            String openid = wxPayScoreResult.getOpenid();
            String startTimeStr = wxPayScoreResult.getTimeRange().getStartTime();
            DateTime startTime = DateUtil.parse(startTimeStr);
//            表示当前单据状态
//            枚举值：
//            CREATED：商户已创建服务订单；
//            DOING：服务订单进行中；
//            DONE：服务订单完成；
//            REVOKED：商户取消服务订单；
//            EXPIRED：服务订单已失效，"商户已创建服务订单"状态超过30天未变动，则订单失效
            String state = wxPayScoreResult.getState();
            OrderInfo orderInfo = new OrderInfo();
            orderInfo.setOpenId(openid);
            orderInfo.setOutTradeNo(outOrderNo);
            orderInfo.setDeviceNo(deviceNo);
            orderInfo.setStartTime(startTime);
            orderInfo.setState(state);
            orderInfo.setCheckStatus(1);
            //落锁
            Result control = deviceInfoService.control(deviceNo, 2);
            if(control.isSuccess()){
                orderInfoService.save(orderInfo);
                return Result.OK();
            }else{
                wxService.getPayScoreService().cancelServiceOrder(outOrderNo, control.getMessage()+"-订单取消");
                return control;
            }
        } catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return Result.error(e.getMessage());
        }

    }

    public static void main(String[] args) {
        long a=67;
//        double ceil = (double) a / 60;
//        int ceil1 =(int) Math.ceil(ceil);
        BigDecimal multiply = new BigDecimal(a).multiply(new BigDecimal("30"));
        int min = Math.min(multiply.intValue(), Integer.parseInt("20000"));
        System.out.println("ceil = " + min);
    }
    @Override
    public Result completeServiceOrder(OrderInfo orderInfo) {
        try {
            SettingInfo settingInfo = settingInfoService.getById(1);
            String freeTime = settingInfo.getFreeTime();
            String hourFee = settingInfo.getHourFee();
            String fixedFee = settingInfo.getFixedFee();
            DateTime endDate = DateUtil.date();
            long between = DateUtil.between(orderInfo.getStartTime(), endDate, DateUnit.MINUTE);
            int amount=0;
            if(between>Integer.parseInt(freeTime)){
                //超出的分钟
                long l = between - Integer.parseInt(freeTime);
//                double ceil = (double) l / 60;
//                int ceil1 =(int) Math.ceil(ceil);
                //超出小时乘以每小时单价
//                BigDecimal multiply = new BigDecimal(ceil1).multiply(new BigDecimal(hourFee));
                //超出每分钟乘以每分钟单价
                BigDecimal multiply = new BigDecimal(l).multiply(new BigDecimal(hourFee));
                amount= Math.min(multiply.intValue(), Integer.parseInt(fixedFee));

            }
            WxPayScoreRequest wxPayScoreRequest = new WxPayScoreRequest();
            wxPayScoreRequest.setOutOrderNo(orderInfo.getOutTradeNo());
            List<PostPayment> postPayments = new ArrayList<>();
            PostPayment postPayment = new PostPayment();
            PostPayment postPayment1 = new PostPayment();
            postPayment1.setName("收费标准");
            BigDecimal hourFee1 = new BigDecimal(settingInfo.getHourFee());
            BigDecimal fixedFee1 = new BigDecimal(settingInfo.getFixedFee());
            BigDecimal h = hourFee1.divide(new BigDecimal("100"));
            BigDecimal f = fixedFee1.divide(new BigDecimal("100"));
            postPayment1.setDescription(h+"元/小时，"+f+"元封顶。");
            postPayment.setName("停车时长");
//            postPayment.setAmount(amount);
            String formatBetween = DateUtil.formatBetween(orderInfo.getStartTime(),endDate, BetweenFormatter.Level.MINUTE);
            postPayment.setDescription(formatBetween);
            postPayments.add(postPayment);
            postPayments.add(postPayment1);
            wxPayScoreRequest.setPostPayments(postPayments);
            wxPayScoreRequest.setTotalAmount(amount);
            TimeRange timeRange = new TimeRange();
            timeRange.setEndTime(DateUtil.format(endDate, "yyyyMMddHHmmss"));
            wxPayScoreRequest.setTimeRange(timeRange);
            WxPayScoreResult wxPayScoreResult = wxService.getPayScoreService().completeServiceOrder(wxPayScoreRequest);
            log.info("wxPayScoreResult:{}", wxPayScoreResult);
            orderInfo.setState(wxPayScoreResult.getState());
            orderInfo.setTotalFee(String.valueOf(amount));
            orderInfo.setEndTime(endDate);
//            orderInfo.setWxOrderId(wxPayScoreResult.getCollection().getDetails().get(0).getTransactionId());
            orderInfoService.updateById(orderInfo);
            return Result.OK(wxPayScoreResult);
        } catch (WxPayException e) {
            e.printStackTrace();
            return Result.error(e.getMessage());
        }
    }
}
